package com.mtable.base;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.SQLException;
import java.util.List;

import javax.annotation.Resource;

import org.hibernate.Hibernate;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.stereotype.Repository;

@Repository
public class BaseDaoImpl<T> implements BaseDao<T> {

	private Class<T> classType;

	private JdbcTemplate jdbcTemplate;
	/**
	 * Can be used within a service implementation via direct instantiation with
	 * a SessionFactory reference, or get prepared in an application context and
	 * given to services as bean reference. Note: The SessionFactory should
	 * always be configured as bean in the application context, in the first
	 * case given to the service directly, in the second case to the prepared
	 * template.
	 */
	@Autowired
	private HibernateTemplate hibernateTemplate;

	@Resource
	public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
		this.hibernateTemplate = hibernateTemplate;
	}

	public BaseDaoImpl() {
		Type type = this.getClass().getGenericSuperclass();
		if (type instanceof ParameterizedType) {
			ParameterizedType pt = (ParameterizedType) type;
			classType = (Class) pt.getActualTypeArguments()[0];
		}
	}

	@Override
	public void delete(T t) {
		this.hibernateTemplate.delete(t);
	}

	@Override
	public List<T> findAll() {
		String queryString = "from " + classType.getName();
		return hibernateTemplate.find(queryString);
	}

	@Override
	public T findById(Integer id) {
		return (T) hibernateTemplate.get(this.classType, id);
	}

	@Override
	public List<T> findByProperty(String propertyName, Object value) {
		String queryString = "from " + classType.getName() + " where "
				+ propertyName + "=";
		if (value instanceof Number) {
			queryString += value;
		} else {
			queryString += "'" + value + "'";
		}
		return hibernateTemplate.find(queryString);
	}

	@Override
	public T merge(T t) {
		return (T) hibernateTemplate.merge(t);
	}

	@Override
	public void save(T t) {
		hibernateTemplate.saveOrUpdate(t);

		// hibernateTemplate.execute(new HibernateCallback<T> (){
		// public Object doInHibernate(Session session)throws
		// HibernateException, SQLException {
		// String hql;
		// Query query = session.createQuery(hql);//创建SESSION
		// query.setFirstResult(1);//分页设置
		// query.setMaxResults(12);
		// List list = query.list();//获取结果结晶
		// return list;//返回值
		// }
		// });
	}
	@Override
	/** 查询指定类的满足条件的持久化对象 */
	public List query(String hql) {
		final String hql1 = hql;
		return hibernateTemplate.executeFind(new HibernateCallback() {
			public Object doInHibernate(Session session)
					throws HibernateException {
				Query query = session.createQuery(hql1);
				return query.list();
			}
		});
	}
	@Override
	/** 分页查询指定类的满足条件的持久化对象 */
	public List query(String hql, int pageNo, int pageSize) {
		final int pNo = pageNo;
		final int pSize = pageSize;
		final String hql1 = hql;
		return hibernateTemplate.executeFind(new HibernateCallback() {
			public Object doInHibernate(Session session)
					throws HibernateException {
				Query query = session.createQuery(hql1);
				query.setMaxResults(pSize);
				query.setFirstResult((pNo - 1) * pSize);
				List result = query.list();
				if (!Hibernate.isInitialized(result))
					Hibernate.initialize(result);
				return result;
			}
		});
	}
	@Override
	/** 统计指定类的所有持久化对象 */
	public int countAll(String clazz) {
		final String hql = "select count(*) from " + clazz + " as a";
		Integer count = (Integer)hibernateTemplate.execute(new HibernateCallback() {
			public Object doInHibernate(Session session)
					throws HibernateException {
				Query query = session.createQuery(hql);
				List list = query.list();
				return Integer.valueOf(list.size());
			}
		});
		return count.intValue();
	}
	@Override
	/** 统计指定类的查询结果 */
	public int countQuery(String hql) {
		final String counthql = hql;
		Integer count = (Integer) hibernateTemplate.execute(
			new HibernateCallback() {
				public Object doInHibernate(Session session)
						throws HibernateException {
					Query query = session.createQuery(counthql);
					List list = query.list();
					return Integer.valueOf(list.size());
				}
			}
		);
		return count.intValue();
	}

	/**
	 * @return the classType
	 */
	public Class<T> getClassType() {
		return classType;
	}

}
